package com.iplant.basic.serviceImpl.dao.fmc;

import com.iplant.base.po.enums.DBSchemas;
import com.iplant.basic.service.po.fmc.FMCResource;
import com.iplant.basic.service.po.fmc.FMCStation;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

public class FMCStationDAO extends BaseDAO {

    private static FMCStationDAO Instance = null;
    private static Logger logger = LoggerFactory.getLogger(FMCStationDAO.class);

    private FMCStationDAO() {
        super();

        setTableName("fmc_station");
    }

    public static FMCStationDAO getInstance() {
        if (Instance == null)
            Instance = new FMCStationDAO();
        return Instance;
    }

    public void FMC_UpdateStation(BMSEmployee wLoginUser, FMCStation wStation, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);

        try {

            this.UpdatePo(wLoginUser, wStation, wErrorCode);

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("FMC_UpdateStation", ex);
        }
    }

    public void FMC_ActiveStation(BMSEmployee wLoginUser, FMCStation wStation, int wActive,
                                  OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);
        // 判断客户信息是否存在(中国：统一社会信用代码，国外:提醒是否有重复）

        try {
            if (wStation == null || wStation.ID <= 0) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }

            Map<String, Object> wParams = new HashMap<String, Object>();

            wParams.put("ID", wStation.ID);
            wParams.put("EditorID", wLoginUser.getID());
            wParams.put("EditTime", Calendar.getInstance());
            wParams.put("Active", wActive);
            super.Update(super.getTableName("fmc_station"), "ID", wParams);

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());

            logger.error("FMC_ActiveStation", ex);
        }
    }

    public List<FMCStation> FMC_QueryStationList(BMSEmployee wLoginUser, int wFactoryID, int wWorkshopID,
                                                 List<Integer> wLineID, int wWorkAreaID, int wDeviceID, String wName,
                                                 int wActive, int wHasResource,
                                                 Pagination wPagination, OutResult<Integer> wErrorCode) {
        return this.FMC_QueryStationList(wLoginUser, -1, "", wFactoryID, wWorkshopID, wLineID, wWorkAreaID, wDeviceID,
                wName, wActive, wHasResource, wPagination, wErrorCode);
    }

    private List<FMCStation> FMC_QueryStationList(BMSEmployee wLoginUser, int wID, String wCode, int wFactoryID,
                                                  int wWorkshopID, List<Integer> wLineID, int wWorkAreaID,
                                                  int wDeviceID, String wName, int wActive,
                                                  int wHasResource, Pagination wPagination,
                                                  OutResult<Integer> wErrorCode) {
        List<FMCStation> wFMCStationList = new ArrayList<FMCStation>();
        wErrorCode.set(0);

        try {
            if (wLineID == null)
                wLineID = new ArrayList<Integer>();

            wLineID.removeIf(p -> p <= 0);
            // Step02:查询
            Map<String, Object> wParams = new HashMap<String, Object>();
            String wSQLText = "";
            wSQLText = StringUtils.Format("Select t.*,t1.Name as WorkAreaName, t1.Code as WorkAreaCode,"
                            + " t2.Name as FactoryName,t2.Code as FactoryCode,t1.WorkshopID,t5.FactoryID,"
                            + " t5.Name as WorkshopName,t5.Code as WorkshopCode,group_concat(distinct t9.Name) as " +
                            "DeviceName,"
                            + " group_concat(distinct t9.Code) as DeviceCode,t3.Name as CreatorName ,t4.Name as " +
                            "EditorName ,"
                            + " group_concat(distinct t8.Code) as StoreCode,  group_concat(distinct t8.Name) as " +
                            "StoreName from {0}.fmc_station t  "
                            + " left join {0}.fmc_workarea t1 on t.WorkAreaID=t1.ID "
                            + " left join {0}.mbs_user t3 on t.CreatorID=t3.ID "
                            + " left join {0}.mbs_user t4 on t.EditorID=t4.ID "
                            + " left join {0}.fmc_workshop t5 on t1.WorkshopID=t5.ID "
                            + " left join {0}.fmc_factory t2 on t5.FactoryID=t2.ID "

                            + " left join {2}.dms_device_ledger t7 on find_in_set(t7.ID,t.DeviceID) "
                            + " left join {2}.ams_asset_list t9 on t7.AssetInfoID=t9.ID "

                            + " left join {0}.wms_store t8 on find_in_set(t8.ID,t.StoreID) and t8.Active=1 "
                            + " where (:ID<=0 or  t.ID=:ID) and (:Code =''''  or  t.Code=:Code)"
                            + " AND (:WorkAreaID<=0 or  t.WorkAreaID=:WorkAreaID)  "
                            + " AND (:WorkshopID<=0 or  t1.WorkshopID=:WorkshopID)  "
                            + " AND (:FactoryID<=0 or  t5.FactoryID=:FactoryID) "
                            + " AND (:Active<0 or  t.Active=:Active) AND (:Name = '''' or  t.Name like :Name)"
                            + " AND (:DeviceID<=0 or find_in_set(:DeviceID,t.DeviceID) )  group by t.ID ",
                    super.getDBName(),
                    wLineID.size() > 0 ? StringUtils.Join(",", wLineID) : "0", DBSchemas.AMS.getDBName());

            wSQLText = this.DMLChange(wSQLText);

            wParams.put("ID", wID);
            wParams.put("FactoryID", wFactoryID);
            wParams.put("WorkAreaID", wWorkAreaID);
            wParams.put("WorkshopID", wWorkshopID);
            wParams.put("Code", wCode);
            wParams.put("Active", wActive);
            wParams.put("DeviceID", wDeviceID);
            wParams.put("Name", StringUtils.isEmpty(wName) ? "" : ("%" + wName + "%"));

            List<Map<String, Object>> wQueryResultList = super.queryForList(wSQLText, wParams, wPagination);
            List<Integer> wStationID = new ArrayList<Integer>();

            FMCStation wFMCStation = null;
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wFMCStation = new FMCStation();
                wFMCStation.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wFMCStation.Code = StringUtils.parseString(wSqlDataReader.get("Code"));
                wFMCStation.Name = StringUtils.parseString(wSqlDataReader.get("Name"));
                wFMCStation.Icon = StringUtils.parseString(wSqlDataReader.get("WorkName"));
                wFMCStation.WorkName = StringUtils.parseString(wSqlDataReader.get("Icon"));
                wFMCStation.WorkAreaID = StringUtils.parseInt(wSqlDataReader.get("WorkAreaID"));
                wFMCStation.WorkAreaCode = StringUtils.parseString(wSqlDataReader.get("WorkAreaCode"));
                wFMCStation.WorkAreaName = StringUtils.parseString(wSqlDataReader.get("WorkAreaName"));
                wFMCStation.FactoryID = StringUtils.parseInt(wSqlDataReader.get("FactoryID"));
                wFMCStation.FactoryCode = StringUtils.parseString(wSqlDataReader.get("FactoryCode"));
                wFMCStation.FactoryName = StringUtils.parseString(wSqlDataReader.get("FactoryName"));
                wFMCStation.WorkshopID = StringUtils.parseInt(wSqlDataReader.get("WorkshopID"));
                wFMCStation.WorkshopCode = StringUtils.parseString(wSqlDataReader.get("WorkshopCode"));
                wFMCStation.WorkshopName = StringUtils.parseString(wSqlDataReader.get("WorkshopName"));

                wFMCStation.DeviceID = StringUtils.parseIntList(wSqlDataReader.get("DeviceID"), ",");
                wFMCStation.DeviceName = StringUtils.parseString(wSqlDataReader.get("DeviceName"));
                wFMCStation.DeviceCode = StringUtils.parseString(wSqlDataReader.get("DeviceCode"));
                wFMCStation.StoreID = StringUtils.parseIntList(wSqlDataReader.get("StoreID"), ",");
                wFMCStation.StoreName = StringUtils.parseString(wSqlDataReader.get("StoreName"));
                wFMCStation.StoreCode = StringUtils.parseString(wSqlDataReader.get("StoreCode"));
                wFMCStation.Active = StringUtils.parseInt(wSqlDataReader.get("Active"));
                wFMCStation.CheckType = StringUtils.parseInt(wSqlDataReader.get("CheckType"));
                wFMCStation.BarCodeType = StringUtils.parseInt(wSqlDataReader.get("BarCodeType"));
                wFMCStation.CreatorID = StringUtils.parseInt(wSqlDataReader.get("CreatorID"));
                wFMCStation.EditorID = StringUtils.parseInt(wSqlDataReader.get("EditorID"));
                wFMCStation.CreatorName = StringUtils.parseString(wSqlDataReader.get("CreatorName"));
                wFMCStation.EditorName = StringUtils.parseString(wSqlDataReader.get("EditorName"));
                wFMCStation.CreateTime = StringUtils.parseCalendar(wSqlDataReader.get("CreateTime"));
                wFMCStation.EditTime = StringUtils.parseCalendar(wSqlDataReader.get("EditTime"));
                wFMCStation.Description = StringUtils.parseString(wSqlDataReader.get("Description"));
                wFMCStation.IsMultiStartSupport = StringUtils.parseInt(wSqlDataReader.get("IsMultiStartSupport"));
                wFMCStation.IsCancelAssemblyCheck = StringUtils.parseInt(wSqlDataReader.get("IsCancelAssemblyCheck"));
                wFMCStation.IsSpotCheck = StringUtils.parseInt(wSqlDataReader.get("IsSpotCheck"));
                wFMCStation.IsRepockCheck = StringUtils.parseInt(wSqlDataReader.get("IsRepockCheck"));
                wFMCStation.FunctionEnumList = StringUtils.parseIntList(StringUtils.parseString(wSqlDataReader.get(
                        "FunctionEnumList")).split(","));

                wFMCStationList.add(wFMCStation);
                if (!wStationID.contains(wFMCStation.ID))
                    wStationID.add(wFMCStation.ID);
            }
            if (wHasResource == 1 && wStationID.size() > 0) {

                List<FMCResource> wResourceList = FMCResourceDAO.getInstance().FMC_QueryResourceList(wLoginUser, "", "",
                        wStationID, -1, -1, -1, -1, -1, Pagination.getMaxSize(), wErrorCode);

                if (wResourceList.size() <= 0)
                    return wFMCStationList;

                Map<Integer, List<FMCResource>> wResourceDic = wResourceList.stream()
                        .collect(Collectors.groupingBy(p -> p.StationID));

                for (FMCStation wStation : wFMCStationList) {
                    if (wStation == null || wStation.ID <= 0 || !wResourceDic.containsKey(wStation.ID))
                        continue;
                    wStation.ResourceList = wResourceDic.get(wStation.ID);
                }

            }

            // Step03:配置系统
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("FMC_QueryStationList", ex);
        }
        return wFMCStationList;
    }

    public FMCStation FMC_QueryStation(BMSEmployee wLoginUser, int wID, String wCode, int wHasResource,
                                       OutResult<Integer> wErrorCode) {
        FMCStation wResult = new FMCStation();
        wErrorCode.set(0);

        try {
            List<FMCStation> wList = null;
            if (wID > 0) {
                wList = this.FMC_QueryStationList(wLoginUser, wID, "", -1, -1, null, -1, -1, "", -1, wHasResource,
                        Pagination.getDefault(), wErrorCode);

            } else if (StringUtils.isNotEmpty(wCode)) {
                wList = this.FMC_QueryStationList(wLoginUser, -1, wCode, -1, -1, null, -1, -1, "", -1, wHasResource,
                        Pagination.getDefault(), wErrorCode);
            }
            if (wList != null && wList.size() > 0) {
                wResult = wList.get(0);
            }
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("FMC_QueryStationByID", ex);
        }
        return wResult;
    }

    public FMCStation FMC_CheckStation(BMSEmployee wLoginUser, FMCStation wFMCStation, OutResult<Integer> wErrorCode) {
        FMCStation wStation = new FMCStation();
        wErrorCode.set(0);

        try {

            // Step0:查询
            Map<String, Object> wParams = new HashMap<String, Object>();
            String wSQLText = StringUtils.Format("Select * from {0}.fmc_station "
                            + " where ID!=:ID and ((WorkAreaID=:WorkAreaID AND  Name =:Name) or (:Code != '''' and " +
                            "Code=:Code)) ",
                    super.getDBName());
            wParams.put("ID", wFMCStation.ID);
            wParams.put("WorkAreaID", wFMCStation.WorkAreaID);
            wParams.put("Name", wFMCStation.Name);
            wParams.put("Code", wFMCStation.Code);

            wSQLText = this.DMLChange(wSQLText);
            List<Map<String, Object>> wQueryResultList = super.queryForList(wSQLText, wParams);
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wStation.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wStation.WorkAreaID = StringUtils.parseInt(wSqlDataReader.get("WorkAreaID"));
                wStation.Name = StringUtils.parseString(wSqlDataReader.get("Name"));
                wStation.Code = StringUtils.parseString(wSqlDataReader.get("Code"));

                wStation.CreatorID = StringUtils.parseInt(wSqlDataReader.get("CreatorID"));
                wStation.CreateTime = StringUtils.parseCalendar(wSqlDataReader.get("CreateTime"));
                wStation.EditorID = StringUtils.parseInt(wSqlDataReader.get("EditorID"));
                wStation.EditTime = StringUtils.parseCalendar(wSqlDataReader.get("EditTime"));
                wStation.Active = StringUtils.parseInt(wSqlDataReader.get("Active"));

            }

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("FMC_CheckStation", ex);
        }
        return wStation;
    }

}
